#include <Windows.h>
#include <memory>
#include <ctime>
#include "DirectX/Enviroment.h"


//#include "Dx11Demo.h"

using namespace DirectX;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  UNREFERENCED_PARAMETER(hPrevInstance);
  UNREFERENCED_PARAMETER(lpCmdLine);

  WNDCLASSEX wndClass;
  ZeroMemory(&wndClass, sizeof(WNDCLASSEX));

  wndClass.cbSize = sizeof(WNDCLASSEX);
  wndClass.style = CS_HREDRAW | CS_VREDRAW;
  wndClass.lpfnWndProc = WndProc;
  wndClass.hInstance = hInstance;
  wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  wndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wndClass.lpszMenuName = NULL;
  wndClass.lpszClassName = "Dx11WindowClass";

  if(!RegisterClassEx(&wndClass))
    return -1;

  RECT rc = { 0,0, 800, 600};
  AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);

  HWND hwnd = CreateWindowA("Dx11WindowClass", "Blank Dx11 Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 
    CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);

  if(!hwnd)
    return -1;

  ShowWindow(hwnd, nShowCmd);
  //std::auto_ptr<Dx11Demo> demo(new Dx11Demo());

  //bool result = demo->Initialize(hInstance, hwnd);
  bool result = CurrentContext::GetInstance().Init(hInstance, hwnd);

  
  if(!result)
    return -1;

  Enviroment env;
  env.LoadContent();



  MSG msg;
  ZeroMemory(&msg, sizeof(MSG));

  POINT point;
  
  if(GetCursorPos(&point))
  {
    CurrentContext::GetInstance().MousePosX = point.x;
    CurrentContext::GetInstance().MousePosY = point.y;
  }

  time_t last, current;
  last = clock();

  while(msg.message != WM_QUIT)
  {
    if(PeekMessage(&msg, 0,0,0, PM_REMOVE))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    else
    {
      /*demo->Update(0.000f);
      demo->Render();*/
      current = clock();
      env.Update((current - last) / 1000.0f);
      env.Render();
      last=current;
    }
  }

  //demo->Shutdown();
  return static_cast<int>(msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT paintStruct;
  HDC hDC;

  switch(msg)
  {
  case WM_WINDOWPOSCHANGING:
  case WM_WINDOWPOSCHANGED:
  case WM_PAINT:
    hDC = BeginPaint(hwnd, &paintStruct);
    EndPaint(hwnd, &paintStruct);
    POINT point;
    if(GetCursorPos(&point))
    {
      CurrentContext::GetInstance().MousePosX = point.x;
      CurrentContext::GetInstance().MousePosY = point.y;
    }
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  
  default:
    return DefWindowProc(hwnd, msg, wParam, lParam);
  }
  return 0;
}